Implement the util type If<C, T, F> which accepts condition C, a truthy value T, and a falsy value F. C is expected to be either true or false while T and F can be any type.
實現一個工具型別 If<C, T, F>
,它接收條件 C,一個為真時的值 T,以及一個為假時的值 F。C 預期為 true 或 false,而 T 和 F 可以是任意型別。
type A = If<true, 'a', 'b'> // expected to be 'a'
type B = If<false, 'a', 'b'> // expected to be 'b'
接下來,你的任務是讓下面的type cases測試通過:
type cases = [
Expect<Equal<MyExclude<'a' | 'b' | 'c', 'a'>, 'b' | 'c'>>,
Expect<Equal<MyExclude<'a' | 'b' | 'c', 'a' | 'b'>, 'c'>>,
Expect<Equal<MyExclude<string | number | (() => void), Function>, string | number>>,
]
在這一關中,我們可以從以下幾個方向來思考:
我們將會用到:
extends 在第三關已經介紹過,可以回到第三關參考喔!
解法:
type If <C extends boolean,T,F > = C extends true? T : F
type A1 = If<true, 6, 3> // 6
type A2 = If<false, 6, 3> // 3
type A3 = If<5, 6, 3> // 3
細節分析:
C extends true ? T : F
:這是 TypeScript 中的條件類型語法,根據 C 是否為 true,返回不同的類型。當 C 是 true 時,返回 T;如果 C 是 false,則返回 F。這是我們實現 If 工具類型的核心邏輯。
extends
?extends 關鍵字用於條件類型檢查。當 C 是 true 時,它會匹配條件,並返回 T;否則會返回 F。這裡的 C extends true 表示檢查 C 是否符合 true 這個類型的條件。
boolean
的意義:在我們的例子中,C 被限制為 boolean 值,這確保了 If 工具類型只會接受 true 或 false 作為 C 的值。如果我們不加這個限制,像 5 這樣的非布林值也能被傳入,但這不符合預期。
延伸問題:
請問 這裡 A4 hover上去結果會是如何呢?
解答:
C
的類型是 boolean
,它可以是 true
或 false
的任何一個,所以 TypeScript 會將 C
視為可能是兩者的 union type (聯合類型) true | false
。在這種情況下,C
既可以符合 true
,也可以符合 false,所以結果會是 T | F
,也就是 6 | 3
。這樣,我們就能順利通過測試啦 🎉 😭 🎉
本次介紹了 If
的實作,下一關會挑戰 Concat
,期待再相見!